package com.yanqu.road.server.gameplayer.module.activity.holiday;

import com.yanqu.road.entity.activity.ActivityDisperseGoldInfo;
import com.yanqu.road.entity.activity.ActivityDisperseGoldResult;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.holiday.ActivityCatMerge;
import com.yanqu.road.entity.activity.holiday.OperateCatsResult;
import com.yanqu.road.entity.activity.holiday.UserHolidayActivityData;
import com.yanqu.road.entity.enums.*;
import com.yanqu.road.entity.log.LogHolidayActivityRecruit;
import com.yanqu.road.entity.task.args.HolidayActivityArgs;
import com.yanqu.road.logic.bussiness.player.UserHolidayActivityBussiness;
import com.yanqu.road.pb.holidayactivity.HolidayActivityProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.ActivityModule;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.BagModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.gameplayer.module.player.DecorationModule;
import com.yanqu.road.server.logic.activity.BaseActivityData;
import com.yanqu.road.server.manger.ServerLanguageMgr;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.HolidayActivityMgr;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.manger.log.LogMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.pb.HolidayActivityPb;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class HolidayActivityModule extends GeneralModule {

    //activityId
    private Map<Integer, UserHolidayActivityData> userHolidayActivityDataMap;      //活动玩法数据

    public HolidayActivityModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        List<Integer> activityIdList = getActivityIdList();
        if(activityIdList.size() == 0){
            userHolidayActivityDataMap = new ConcurrentHashMap<>();
        }else {
            userHolidayActivityDataMap = UserHolidayActivityBussiness.getUserActivityDataMap(player.getUserId(), activityIdList);
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return true;
    }

    @Override
    public boolean saveData() {
        for(UserHolidayActivityData userHolidayActivityData : userHolidayActivityDataMap.values()){
            if(userHolidayActivityData.isInsertOption()){
                UserHolidayActivityBussiness.addUserHolidayActivityData(userHolidayActivityData);
            }else if(userHolidayActivityData.isUpdateOption()){
                UserHolidayActivityBussiness.updateUserHolidayActivityData(userHolidayActivityData);
            }
        }
        return true;
    }

    @Override
    public void afterLogin() {
        syncActivity();
    }

    @Override
    public void loginSendMsg() {

    }

    private void syncUserCatsMergeDataList() {
        List<Integer> activityIdList = getActivityIdList();
        if(activityIdList.size() > 0) {
            HolidayActivityProto.UserCatsMergeDataListMsg.Builder respMsg = HolidayActivityProto.UserCatsMergeDataListMsg.newBuilder();
            for (Integer activityId : activityIdList) {
                HolidayActivityProto.UserCatsMergeDataTemp.Builder userCatsMergeDataTemp = HolidayActivityPb.parseUserCatsMergeDataTempBuilder(HolidayActivityMgr.getCatsInfoByActivityId(activityId), getUserHolidayActivityDataByActivityId(activityId));
                respMsg.addUserCatsDataList(userCatsMergeDataTemp);
            }
            player.sendPacket(ClientProtocol.U_HOLIDAY_ACTIVITY_USER_DATA_LIST, respMsg);
        }
    }

    private void syncUserCatsMergeDataList(int activityId) {
        HolidayActivityProto.UserCatsMergeDataListMsg.Builder respMsg = HolidayActivityProto.UserCatsMergeDataListMsg.newBuilder();
        HolidayActivityProto.UserCatsMergeDataTemp.Builder userCatsMergeDataTemp = HolidayActivityPb.parseUserCatsMergeDataTempBuilder(HolidayActivityMgr.getCatsInfoByActivityId(activityId), getUserHolidayActivityDataByActivityId(activityId));
        respMsg.addUserCatsDataList(userCatsMergeDataTemp);
        player.sendPacket(ClientProtocol.U_HOLIDAY_ACTIVITY_USER_DATA_LIST, respMsg);
    }

    public void reloadUserData(){

    }

    private void syncCatMergeList() {
        Map<Integer, Map<Integer, ActivityCatMerge>> map = HolidayActivityMgr.getActivityCatMergeMap();
        if(map.size() > 0) {
            HolidayActivityProto.CatMergeListMsg.Builder respMsg = HolidayActivityProto.CatMergeListMsg.newBuilder();
            for (Map.Entry<Integer, Map<Integer, ActivityCatMerge>> dataEntry : map.entrySet()) {
                HolidayActivityProto.CatMergeListTemp.Builder catListTemp = HolidayActivityPb.parseCatMergeListMsg(dataEntry.getKey(), dataEntry.getValue());
                try {
                    for (HolidayActivityProto.CatMergeTemp.Builder builder : catListTemp.getCatListBuilderList()) {
                        builder.setDesc(ServerLanguageMgr.getContent(builder.getDesc(), player.getUserInfo().getLanguage()));
                        builder.setName(ServerLanguageMgr.getContent(builder.getName(), player.getUserInfo().getLanguage()));
                    }
                } catch (Exception ex) {
                    log.error(ex);
                }

                respMsg.addActivityCatList(catListTemp);
            }
            player.sendPacket(ClientProtocol.U_HOLIDAY_ACTIVITY_CAT_LIST_DATA, respMsg);
        }
    }

    /**
     * 自动将活动道具转为活动积分
     * @param activityInfoList
     */
    public void autoUseActivityGoods(List<ActivityInfo> activityInfoList){
        if(null != activityInfoList && activityInfoList.size() >0){
            for(ActivityInfo activityInfo : activityInfoList){
                autoUseActivityGoods(activityInfo);
            }
        }
    }

    private void autoUseActivityGoods(ActivityInfo activityInfo){
        if(ActivityMgr.activityInShowPeriod(activityInfo) || ActivityMgr.activityInRewardPeriod(activityInfo)){//在展示期或者领奖期
           /* List<Integer> param4List = HolidayActivityMgr.getActivityParam4(activityInfo);
            int zhaoMuGoodsId = param4List.get(0);
            player.getModule(BagModule.class).removeHolidayActivityBagItem(activityInfo, zhaoMuGoodsId);*/
        }
    }

    public BaseActivityData getBaseActivityData(int activityId){
      return  player.getModule(ActivityModule.class).getBaseActivityData(activityId);
    }

    public List<Integer> getActivityIdList(){
        List<Integer> activityIdList = new ArrayList<>();
        List<ActivityInfo> activityInfoList = NormalActivityMgr.getOpenActivityInfoList(eActivityType.CrossHolidayActivity.getValue());
        for(ActivityInfo activityInfo : activityInfoList){
            activityIdList.add(activityInfo.getActivityId());
        }
        return activityIdList;
    }

    public UserHolidayActivityData getUserHolidayActivityDataByActivityId(int activityId) {
        UserHolidayActivityData userHolidayActivityData =  userHolidayActivityDataMap.get(activityId);
        if(userHolidayActivityData == null){
            synchronized (userHolidayActivityDataMap) {
                userHolidayActivityData =  userHolidayActivityDataMap.get(activityId);
                if(userHolidayActivityData == null) {
                    userHolidayActivityData = new UserHolidayActivityData();
                    userHolidayActivityData.setInsertOption();
                    userHolidayActivityData.setUserId(player.getUserId());
                    userHolidayActivityData.setActivityId(activityId);
                    userHolidayActivityData.initCats();
                    userHolidayActivityDataMap.put(activityId, userHolidayActivityData);
                }
            }
        }
        return userHolidayActivityData;
    }

    /**
     * 招募
     * @param activityInfo  活动
     * @param recruitTimes   招募次数
     * @return
     */
    public OperateCatsResult recruitCats(ActivityInfo activityInfo, int recruitTimes){
        OperateCatsResult result = new OperateCatsResult();
        UserHolidayActivityData userHolidayActivityData = getUserHolidayActivityDataByActivityId(activityInfo.getActivityId());
        ActivityCatMerge catMerge = HolidayActivityMgr.getCatsInfoByActivityIdAndLevel(activityInfo.getActivityId(), userHolidayActivityData.getCats().length -1);//第九级别
        List<Integer> recruitList = new ArrayList<>();
        synchronized (userHolidayActivityData) {
            int times = userHolidayActivityData.getRecruitTimes();
            for (int t = 0; t < recruitTimes; t++) {
                int level = HolidayActivityMgr.getRandomCatsLevel(activityInfo.getActivityId());

                times++;
                if(catMerge != null){  //根据出现频率改变level
                    if(catMerge.getFrequency() > 0 && times % catMerge.getFrequency() == 0){
                        level = userHolidayActivityData.getCats().length - 1;
                    }
                }
                userHolidayActivityData.setCats(level, userHolidayActivityData.getCats(level) + 1);
                result.getReward().addProperty(level, BigInteger.ONE);
                recruitList.add(level);
            }
            userHolidayActivityData.setRecruitTimes(userHolidayActivityData.getRecruitTimes() + recruitTimes);
        }
        int recruitType = 1;
        int num = 1;
        if(recruitTimes == 10){
            recruitType = 2;
            num = recruitTimes - 1;
        }
        List<Integer> param4List = HolidayActivityMgr.getActivityParam4(activityInfo);
        long nowNum = player.getModule(BagModule.class).getUserBagItemCount(param4List.get(0));
        //后台日志
        AutoLogMgr.add(new LogHolidayActivityRecruit(player.getUserId(), activityInfo.getActivityId(), recruitType, recruitList, num, nowNum, System.currentTimeMillis()));
        return result;
    }

    /**
     * 自动合成
     * @param activityInfo 活动
     * @return
     */
    public OperateCatsResult autoMergeCats(ActivityInfo activityInfo){
        UserHolidayActivityData userHolidayActivityData = getUserHolidayActivityDataByActivityId(activityInfo.getActivityId());
        OperateCatsResult result = new OperateCatsResult();

        long score = 0L;
        synchronized (userHolidayActivityData) {
            int[] oldCats = userHolidayActivityData.copyCats();
            for (int level = 1; level < userHolidayActivityData.getCats().length; level++) {
                int loop = 0;
                int maxLoop = 100000;
                ActivityCatMerge catMerge = HolidayActivityMgr.getCatsInfoByActivityIdAndLevel(activityInfo.getActivityId(), level);
                while (userHolidayActivityData.getCats(level) >= catMerge.getMergeNum()) {
                    loop++;
                    if(loop > maxLoop){
                        break;
                    }
                    //灵猫数量变更
                    userHolidayActivityData.setCats(level, userHolidayActivityData.getCats(level) - catMerge.getMergeNum());
                    if(level != userHolidayActivityData.getCats().length -1){
                        userHolidayActivityData.setCats(level + 1, userHolidayActivityData.getCats(level + 1) + 1);
                    }
                    //合成积分累加
                    score += HolidayActivityMgr.getCatsInfoByActivityIdAndLevel(activityInfo.getActivityId(), level + 1).getScore();
                    if (level == userHolidayActivityData.getCats().length -1) {//有合成最高级
                        //南瓜数量+1
                        userHolidayActivityData.setProgressVal(userHolidayActivityData.getProgressVal().add(BigInteger.ONE));
                        player.notifyListener(eGamePlayerEventType.HolidayActivityProgress.getValue(), new HolidayActivityArgs(activityInfo.getChildType(), userHolidayActivityData.getProgressVal()));

                        //南瓜数增加，是否增加送糖数据
                        List<String> param3List = HolidayActivityMgr.getActivityParam3(activityInfo);
                        String petTimeNeedScore = param3List.get(1);
                        BigInteger nowScore = userHolidayActivityData.getProgressVal();
                        long allTimes = calcAllTimes(nowScore.longValue(), petTimeNeedScore);
                        if(allTimes > 0) {
                            userHolidayActivityData.setHasTimes(BigInteger.valueOf(allTimes - userHolidayActivityData.getUseTimes()).intValue());
                        }
                        //十级奖励
                        result.getReward().addProperty(level + 1, BigInteger.ONE);
                    }
                }
            }
            int[] newCats = userHolidayActivityData.getCats();
            for (int i = 0; i < newCats.length; i++) {
                if (newCats[i] > oldCats[i]) {
                    //新获得的灵猫级别及数量
                    result.getReward().addProperty(i + 1, BigInteger.valueOf(newCats[i] - oldCats[i]));
                }
            }

            if(score != 0){
                //param4配置，招募令id|积分id|糖果id
                List<Integer> param4List = HolidayActivityMgr.getActivityParam4(activityInfo);
                BigInteger val = BigInteger.valueOf(score);
                result.getReward().setGood(param4List.get(1), val);
                Property goodsProperty = new Property();
                goodsProperty.addProperty(param4List.get(1), val);
                player.getModule(CurrencyModule.class).addCurrency(goodsProperty, eLogMoneyType.Activity, eLogMoneyType.HolidayActivityScoreReward);
                userHolidayActivityData.setMergeScore(userHolidayActivityData.getMergeScore().add(val));
                player.notifyListener(eGamePlayerEventType.HolidayActivityScoreCrossRank.getValue(), new HolidayActivityArgs(activityInfo.getChildType(), userHolidayActivityData.getMergeScore()));
                player.notifyListener(eGamePlayerEventType.HolidayActivityScoreRank.getValue(), new HolidayActivityArgs(activityInfo.getChildType(), userHolidayActivityData.getMergeScore()));
            }else{
                result.setRet(GameErrorCode.E_HOLIDAY_ACTIVITY_NO_COMPOSE_CATS);
            }
        }
        return result;
    }

    private long calcAllTimes(long nowScore, String petTimeNeedScore) {
        int times = 0;
        String[] scoreNeedArr = petTimeNeedScore.split(";");
        while (nowScore >= getNeedScore(times, scoreNeedArr)) {
            nowScore = nowScore - getNeedScore(times, scoreNeedArr);
            times ++;
        }
        return times;
    }

    private long getNeedScore(int times, String[] scoreNeedArr) {
        if (times >= scoreNeedArr.length) {
            times = scoreNeedArr.length - 1;
        }
        return Long.parseLong(scoreNeedArr[times]);
    }


    /**
     * 活动送财
     * @param activityInfo
     * @return
     */
    public ActivityDisperseGoldResult disperseGold(ActivityInfo activityInfo, String manifesto) {
        ActivityDisperseGoldResult result = new ActivityDisperseGoldResult();
        UserHolidayActivityData userHolidayActivityData = getUserHolidayActivityDataByActivityId(activityInfo.getActivityId());
        if (userHolidayActivityData.getHasTimes() <= 0) {
            result.setRet(GameErrorCode.E_HOLIDAY_DISPERSE_CANDY_TIMES_NO_ENOUGH);         //送糖次数不足
            return result;
        }
        List<String> param3List = HolidayActivityMgr.getActivityParam3(activityInfo);
        if (userHolidayActivityData.getMergeScore().compareTo(new BigInteger(param3List.get(0))) < 0) {
            result.setRet(GameErrorCode.E_HOLIDAY_ACTIVITY_SCORE_NO_ENOUGH);             //活动积分不足
            return result;
        }

        synchronized (userHolidayActivityData) {
            userHolidayActivityData.setHasTimes(userHolidayActivityData.getHasTimes() - 1);
            userHolidayActivityData.setUseTimes(userHolidayActivityData.getUseTimes() + 1);
        }

        syncUserCatsMergeDataList(activityInfo.getActivityId());

        List<Integer> decorationIdList = player.getModule(DecorationModule.class).getDecorationIdList(eDecorationType.HonoraryTitle.getValue());
        ActivityDisperseGoldInfo goldInfo = new ActivityDisperseGoldInfo();
        goldInfo.setActivityId(activityInfo.getActivityId());
        goldInfo.setType(activityInfo.getType());
        goldInfo.setUserId(player.getUserId());
        goldInfo.setManifesto(manifesto);
        goldInfo.setBeginTime(System.currentTimeMillis());
        goldInfo.setHonoraryTitles(StringUtils.listToString(decorationIdList, ","));
        if(NormalActivityMgr.hasConditionType(activityInfo.getActivityId(), eGamePlayerEventType.HolidayActivityScoreCrossRank.getValue())) {
            goldInfo.setServerList(activityInfo.getServerIdList());
        }else {
            List<Long> serverList = new ArrayList<>();
            serverList.add(GameServer.getInstance().getServerId());
            goldInfo.setServerList(serverList);
        }
        goldInfo.setUserBaseInfo(UserMgr.getUserBaseInfo(player.getUserId(), GameServer.getInstance().getServerId()));
        result.setGoldInfo(goldInfo);
        return result;
    }

    /**
     * 系统解锁
     */
    public void initSystem() {
        syncUserCatsMergeDataList();
        syncCatMergeList();
        autoUseActivityGoods(NormalActivityMgr.getOpenActivityInfoList(eActivityType.CrossHolidayActivity.getValue()));
    }

    public void syncActivity() {
        if(SystemOpenMgr.systemOpen(player, eSystemId.CatTreasure.getValue())){
            syncUserCatsMergeDataList();
            syncCatMergeList();
            autoUseActivityGoods(NormalActivityMgr.getOpenActivityInfoList(eActivityType.CrossHolidayActivity.getValue()));
        }
    }
}
